/*
 * ColorsHSV.h
 *
 *  Created on: Feb 19, 2009
 *      Author: vuk
 */

#ifndef _COLORSHSV_H_
#define _COLORSHSV_H_

#include "structures.h"

#include <iostream>
#define uchar unsigned char

enum TYPE_ENUM {
	RED = 0,
	GREEN,
	BLUE,
	EMPTY,
	BROWN
	};

using namespace std;


//Jednostavna klasa za HSV boje

class ColorHSV
{

	protected:
		uchar *hsv;

	public:
                                
		void set(HSV & color)
		{
			hsv[0] = color.h;
			hsv[1] = color.s;
			hsv[2] = color.v;
		}

	//bez destruktora zbog efikasnosti
	//nemora se raditi koporanje

		ColorHSV()
		{
			hsv = new uchar[3];
			hsv[0]=0;
			hsv[1]=0;
			hsv[2]=0;
		}

		ColorHSV(uchar *u){hsv=u;}

		ColorHSV(uchar H, uchar S, uchar V)
		{
			hsv = new uchar[3];
			hsv[0]=H;
			hsv[1]=S;
			hsv[2]=V;
		}

		void set(uchar H, uchar S, uchar V)
		{
			hsv[0]=H;
			hsv[1]=S;
			hsv[2]=V;
		}

		uchar H()	{	return hsv[0];}
		uchar S()	{	return hsv[1];}
		uchar V()	{	return hsv[2];}

		void setH(uchar c)	{	hsv[0]=c;}
		void setS(uchar c)	{	hsv[1]=c;}
		void setV(uchar c)	{	hsv[2]=c;}

		void operator = (uchar *a)
		{
			hsv = a;
		}

		bool operator>(ColorHSV &c) { return (hsv[0]>c.hsv[0] && hsv[1]>c.hsv[1] && hsv[2]>c.hsv[2]);}
		bool operator<(ColorHSV &c) { return (hsv[0]<c.hsv[0] && hsv[1]<c.hsv[1] && hsv[2]<c.hsv[2]);}
		bool operator<=(ColorHSV &c) { return (hsv[0]<=c.hsv[0] && hsv[1]<=c.hsv[1] && hsv[2]<=c.hsv[2]);}
		bool operator>=(ColorHSV &c) { return (hsv[0]>=c.hsv[0] && hsv[1]>=c.hsv[1] && hsv[2]>=c.hsv[2]);}
		bool operator==(ColorHSV &c) { return (hsv[0]==c.hsv[0] && hsv[1]==c.hsv[1] && hsv[2]==c.hsv[2]);}
		bool operator!=(ColorHSV &c) { return (hsv[0]!=c.hsv[0] && hsv[1]!=c.hsv[1] && hsv[2]!=c.hsv[2]);}

		bool horeH(ColorHSV &c) { return hsv[0]>=c.hsv[0]; } //koristi se kao vece  jednako ali, samo proverava H
		bool loreH(ColorHSV &c) { return hsv[0]<=c.hsv[0]; } //koristi se kao manje jednako, ali samo proverava H

		bool horeSV(ColorHSV &c) { return hsv[1]>=c.hsv[1] && hsv[2]>=c.hsv[2]; } //koristi se kao vece  jednako, ali samo proverava S i V
		bool loreSV(ColorHSV &c) { return hsv[1]<=c.hsv[1] && hsv[2]<=c.hsv[2]; } //koristi se kao manje jednako, ali samo proverava S i V

		bool horeH(int x) { return hsv[0]>=x; } //koristi se kao vece  jednako ali, samo proverava H
		bool loreH(int x) { return hsv[0]<=x; } //koristi se kao manje jednako, ali samo proverava H

		friend ostream &operator<<(ostream &out, const ColorHSV& c)
		{
			return out<<" "<<(int)c.hsv[0]<<" "<<(int)c.hsv[1]<<" "<<(int)c.hsv[2]<<endl;
		}

};

//Klasa koja organizuje HSV boje u skup svih boja koje mogu da se jave
//Ona konstruise pomocu fajla a takodje moze i da snimi u bilo koji fajl promene parametara

class ColorsHSV
{
	public:

		ColorHSV rl,rh,gl,gh,bl,bh,dl,dh; //d=dark, braon l=donja h=gornja

		class BadFile{};

		void _initialize(Filter& red, Filter& green, Filter& blue, Filter& brown)
		{
			rl.set(red.bottom);
			rh.set(red.top);
			gl.set(green.bottom);
			gh.set(green.top);
			bl.set(blue.bottom);
			bh.set(blue.top);
			dl.set(brown.bottom);
			dh.set(brown.top);
		}

		ColorsHSV ()//const char *fajl)
		{
/*			ifstream f(fajl);
			int h,s,v;
			string str;

			f>>str;
			if (str!="Crvena_donja:")	throw BadFile();
			f>>h>>s>>v;
			rl.set(h, s, v);

			f>>str;
			if(str!="Crvena_gornja:")	throw BadFile();
			f>>h>>s>>v;
			rh.set(h, s, v);

			f>>str;
			if(str!="Zelena_donja:")	throw BadFile();
			f>>h>>s>>v;
			gl.set(h, s, v);

			f>>str;
			if(str!="Zelena_gornja:")	throw BadFile();
			f>>h>>s>>v;
			gh.set(h, s, v);

			f>>str;
			if(str!="Plava_donja:")	throw BadFile();
			f>>h>>s>>v;
			bl.set(h, s, v);

			f>>str;
			if(str!="Plava_gornja:")	throw BadFile();
			f>>h>>s>>v;
			bh.set(h, s, v);

			f>>str;
			if(str!="Braon_donja:")	throw BadFile();
			f>>h>>s>>v;
			dl.set(h, s, v);

			f>>str;
			if(str!="Braon_gornja:")	throw BadFile();
			f>>h>>s>>v;
			dh.set(h, s, v);
*/
		}

		friend istream &operator>>(istream &f, ColorsHSV &c)
		{
/*			int h,s,v;
			string str;

			f>>str;
			if(str!="Crvena_donja:")	throw BadFile();
			f>>h>>s>>v;
			c.rl.set(h, s, v);

			f>>str;
			if(str!="Crvena_gornja:")	throw BadFile();
			f>>h>>s>>v;
			c.rh.set(h, s, v);

			f>>str;
			if(str!="Zelena_donja:")	throw BadFile();
			f>>h>>s>>v;
			c.gl.set(h, s, v);

			f>>str;
			if(str!="Zelena_gornja:")	throw BadFile();
			f>>h>>s>>v;
			c.gh.set(h, s, v);

			f>>str;
			if(str!="Plava_donja:")	throw BadFile();
			f>>h>>s>>v;
			c.bl.set(h, s, v);

			f>>str;
			if(str!="Plava_gornja:")	throw BadFile();
			f>>h>>s>>v;
			c.bh.set(h, s, v);

			f>>str;
			if(str!="Braon_donja:")	throw BadFile();
			f>>h>>s>>v;
			c.dl.set(h, s, v);

			f>>str;
			if(str!="Braon_gornja:")	throw BadFile();
			f>>h>>s>>v;
			c.dh.set(h, s, v);
*/
		}
	
	//proveri da li je data boja u opsegu crvene
		bool r(ColorHSV c)
		{
			//switch (type)
			//{
			//case RED:
				if(rl.loreH(rh))
					return rl<=c && rh>=c;
				else
					return ( (c.horeH(rl) && c.loreH(180) ) || (c.horeH(0) && c.loreH(rh) ) ) && c.horeSV(rl) && c.loreSV(rh);
			//	break;
			/*
			case GREEN:
				if(gl.loreH(gh))
					return gl<=c && gh>=c;
				else
					return ( (c.horeH(rl) && c.loreH(180) ) || (c.horeH(0) && c.loreH(rh) ) ) && c.horeSV(rl) && c.loreSV(rh);
				break;
			
			case BLUE:
				if(bl.loreH(bh))
					return bl<=c && bh>=c;
				else
					return ( (c.horeH(bl) && c.loreH(180) ) || (c.horeH(0) && c.loreH(bh) ) ) && c.horeSV(bl) && c.loreSV(bh);
			
			default:
			case EMPTY:
				if(dl.loreH(dh))
					return dl<=c && dh>=c;
				else
					return ( (c.horeH(dl) && c.loreH(180) ) || (c.horeH(0) && c.loreH(dh) ) ) && c.horeSV(dl) && c.loreSV(dh);
				break;
			}
			*/
		}

	//proveri da li je data boja u opsegu zelene
		bool g(ColorHSV c)
		{
			if(gl.loreH(gh))
				return gl<=c && gh>=c;
			else
				return ( (c.horeH(rl) && c.loreH(180) ) || (c.horeH(0) && c.loreH(rh) ) ) && c.horeSV(rl) && c.loreSV(rh);
		}
	//proveri da li je data boja u opsegu plave
		bool b(ColorHSV c)
		{
			if(bl.loreH(bh))
				return bl<=c && bh>=c;
			else
				return ( (c.horeH(bl) && c.loreH(180) ) || (c.horeH(0) && c.loreH(bh) ) ) && c.horeSV(bl) && c.loreSV(bh);
		}
	//proveri da li je data boja u opsegu braon
		bool d(ColorHSV c)
		{
			if(dl.loreH(dh))
				return dl<=c && dh>=c;
			else
				return ( (c.horeH(dl) && c.loreH(180) ) || (c.horeH(0) && c.loreH(dh) ) ) && c.horeSV(dl) && c.loreSV(dh);
		}




		friend ostream &operator<<(ostream &out, const ColorsHSV& c)
		{
			return 	out<<"Crvena_donja:"<< c.rl<< "Crvena_gornja:"<< c.rh
					<<"Zelena_donja:"<< c.gl<< "Zelena_gornja:"<< c.gh
					<<"Plava_donja:"<< c.bl<< "Plava_gornja:"<< c.bh
					<<"Braon_donja:"<< c.dl<< "Braon_gornja:"<< c.dh;
		}
};

 

#endif /* COLORSHSV_H_ */
